#include "Boss.h"
#include <math.h>
#define PI 3.14159265


#pragma region Base
Boss::Boss() {
}


Boss::~Boss() {
}

#pragma endregion


#pragma region Publics

void Boss::Initialize(sf::RenderWindow* window, Player* player, sf::Texture* walkImage, sf::Texture* hitBoxImage, sf::Texture* attackImage) {
	m_renderWindow = window;
	m_player = player;

	m_hitBoxImg = hitBoxImage;
	m_walkImg = walkImage;

	m_attackAnimation = new Animation();
	m_attackAnimation->Initialize(attackImage, sf::Vector2f(242, 270), 14, 14);

	m_hitBox = new sf::Sprite();
	m_hitBox->setTexture(*m_hitBoxImg);
	m_hitBox->setOrigin(m_hitBoxImg->getSize().x, m_hitBoxImg->getSize().y / 2);

	m_walkAnimation = new Animation();
	m_walkAnimation->Initialize(m_walkImg, sf::Vector2f(270, 270), 26, 12);
	
	m_sprite = new sf::Sprite();
	
	m_isBusy = false;
	clockRestarted = false;

	m_clock = new sf::Clock();
	playerDown = false;
	
	boss_speed = 20.0f;
	m_attackSprite = new sf::Sprite();
	m_attackSprite->setTexture(*attackImage);

	m_attackClock = new sf::Clock();
	m_chaseClock = new sf::Clock();
	hasStartedChasing = false;
	m_health = 100;
	
}

void Boss::Update(){
		timeSinceLastFrame = m_clock->restart();

		playerAngle = atan2(((m_player->m_playerSprite->getPosition().y) - m_sprite->getPosition().y), ((m_player->m_playerSprite->getPosition().x) - m_sprite->getPosition().x));
		shipAngle = atan2((720 - (m_sprite->getPosition().y)), (1280 - (m_sprite->getPosition().x)));

		// Distance between mutants and (ship)
		if (m_sprite->getPosition().x < 1280) {
			distanceXship = 1280 - m_sprite->getPosition().x;
		} else if (m_sprite->getPosition().x > 1280) {
			distanceXship = m_sprite->getPosition().x - 1280;
		}
		if (m_sprite->getPosition().y < 720) {
			distanceYship = 720 - m_sprite->getPosition().y;
		} else if (m_sprite->getPosition().y > 720) {
			distanceYship = m_sprite->getPosition().y -720;
		}
		// Distance between mutants and player
		if(m_sprite->getPosition().x < m_player->m_playerSprite->getPosition().x) {
			distanceXplayer = m_player->m_playerSprite->getPosition().x - m_sprite->getPosition().x;
		} else if (m_sprite->getPosition().x > m_player->m_playerSprite->getPosition().x) {
			distanceXplayer = m_sprite->getPosition().x - m_player->m_playerSprite->getPosition().x;
		}

		if(m_sprite->getPosition().y < m_player->m_playerSprite->getPosition().y) {
			distanceYplayer = m_player->m_playerSprite->getPosition().y - m_sprite->getPosition().y;
		} else if (m_sprite->getPosition().y > m_player->m_playerSprite->getPosition().y) {
			distanceYplayer = m_sprite->getPosition().y - m_player->m_playerSprite->getPosition().y;
		}


		// Calculate distance to player and ship
		distancePlayer = sqrt(distanceXplayer*distanceXplayer + distanceYplayer*distanceYplayer);
		distanceShip = sqrt(distanceXship*distanceXship + distanceYplayer*distanceYplayer);
		
		if (playerDown == false) {
			if(distancePlayer <= distanceShip && chaseTime.asSeconds() < 5.0f) {

				if(distancePlayer <= 200)
				{
					if(hasStartedChasing == false)
					{
						m_chaseClock->restart();
						hasStartedChasing = true;
					}
				}
				if(hasStartedChasing == true)
				{
					chaseTime += m_chaseClock->restart();
				}

		
				//m_sprite->setRotation(playerAngle * 180 / PI * 1 + 180);
				m_sprite->setRotation(playerAngle * 180 / PI);

				m_sprite->move(boss_speed * cos(playerAngle) * timeSinceLastFrame.asSeconds(),
				boss_speed * sin(playerAngle) * timeSinceLastFrame.asSeconds());
			}
		}

					
		if(distancePlayer > distanceShip || chaseTime.asSeconds() > 5.0f || playerDown == true) {
			//m_sprite->setRotation(shipAngle * 180 / PI * 1 + 180);
			m_sprite->setRotation(shipAngle * 180 / PI);
			clockRestarted = false;
			m_sprite->move(boss_speed * cos(shipAngle) * timeSinceLastFrame.asSeconds(),
			boss_speed * sin(shipAngle) * timeSinceLastFrame.asSeconds());
		}
		
		m_hitBox->setPosition(m_sprite->getPosition());
		m_hitBox->setRotation(m_sprite->getRotation());

		m_walkAnimation->GetSprite()->setPosition(m_sprite->getPosition());
		m_attackAnimation->GetSprite()->setPosition(m_sprite->getPosition());
		m_attackAnimation->GetSprite()->setRotation(m_sprite->getRotation());


		if(boss_speed == 20.0f)
		{
			m_sprite = m_walkAnimation->GetSprite();
			m_sprite->setOrigin(135, 135);
			m_walkAnimation->Update(timeSinceLastFrame.asSeconds());	
		}
		if (boss_speed == 0) {
			m_sprite = m_attackAnimation->GetSprite();
			m_sprite->setOrigin(121, 135);
			m_attackAnimation->Update(timeSinceLastFrame.asSeconds());
		}

		boss_speed = 20.0f;
		
		m_renderWindow->draw(*m_sprite);
		
}

void Boss::attack_player()
{
	if (playerDown == true) {
			boss_speed = 20.0f;
	} else {
		boss_speed = 0.0f;
	}
			m_attackTimer += m_attackClock->restart();
		

		if(m_attackTimer.asSeconds() > 1.0f)
		{
			m_player->m_playerHealth -= 30.0f;
			m_attackTimer -= m_attackTimer;
		}
}

void Boss::attack_ship()
	{
		
			boss_speed = 0;
			
			m_attackTimer += m_attackClock->restart();
		

		if(m_attackTimer.asSeconds() > 1.0f)
		{
			m_player->shipHealth -= 50;
			m_attackTimer -= m_attackTimer;
			
		}
	}

void Boss::Cleanup() {

	delete m_hitBox;
	delete m_sprite;
	delete m_attackSprite;
	delete m_clock;
	delete m_chaseClock;
	delete m_attackClock;
	delete m_walkAnimation;
	delete m_attackAnimation;

}



bool Boss::IsBusy() { 
	return m_isBusy;
}

void Boss::Destroy() {
	m_isBusy = false; 
}


sf::FloatRect Boss::GetRect() { 
	return sf::FloatRect(m_sprite->getPosition().x, m_sprite->getPosition().y,
	m_sprite->getPosition().x + m_sprite->getGlobalBounds().width, m_sprite->getPosition().y + m_sprite->getGlobalBounds().height);
}



#pragma endregion